package org.spiderflow.core.expression.parsing.ast.operation;

import org.spiderflow.core.expression.ExpressionError;
import org.spiderflow.core.expression.ExpressionTemplate;
import org.spiderflow.core.expression.ExpressionTemplateContext;
import org.spiderflow.core.expression.parsing.Span;
import org.spiderflow.core.expression.parsing.ast.Expression;

import java.io.IOException;

/**
 * A ternary operation is an abbreviated if/then/else operation, and equivalent to the the ternary operator in Java.
 *
 * @author zsh
 */
public class TernaryOperation extends Expression {
    private final Expression condition;
    private final Expression trueExpression;
    private final Expression falseExpression;

    public TernaryOperation(Expression condition, Expression trueExpression, Expression falseExpression) {
        super(new Span(condition.getSpan(), falseExpression.getSpan()));
        this.condition = condition;
        this.trueExpression = trueExpression;
        this.falseExpression = falseExpression;
    }

    public Expression getCondition() {
        return condition;
    }

    public Expression getTrueExpression() {
        return trueExpression;
    }

    public Expression getFalseExpression() {
        return falseExpression;
    }

    @Override
    public Object evaluate(ExpressionTemplate template, ExpressionTemplateContext context) throws IOException {
        Object evaluate = getCondition().evaluate(template, context);
        if (!(evaluate instanceof Boolean)) {
            throw ExpressionError.error("Condition of ternary operator must be a boolean, got " + evaluate + ".", getSpan());
        }
        return Boolean.TRUE.equals(evaluate) ? getTrueExpression().evaluate(template, context) : getFalseExpression().evaluate(template, context);
    }
}